﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FeedbackNetwork.network
{
    public class Tensor<T>
    {
        protected T[] data;
        protected int[] shape;
        protected TensorType dtype;

        public Tensor() {
        }

        public Tensor(T[] data, int[] shape, TensorType dtype)
        {
            this.SetData(data, shape, dtype);
        }

        public Tensor(Tensor<T> m)
        {
            this.SetData(m.GetData(), m.GetShape(), m.GetDType());
        }

        public void SetData(T[] data, int[] shape, TensorType dtype)
        {
            if (shape == null) throw new ArgumentException("参数不能为空", "shape");
            this.shape = shape;
            int sum = this.GetLength();

            if (sum != data.Length) throw new ArgumentException("data的长度与shape形状长度不匹配");
            else
            {
                this.dtype = dtype;
                this.shape = shape;
                this.data = new T[sum];
                for (int i = 0; i < sum; i++)
                    this.data[i] = data[i];
            }
        }

        public void SetData(T data, int[] pos, TensorType dtype)
        {
            int index = 0;
            int offset = 1;
            for (int i = pos.Length - 2; i >= 0; i--)
            {
                offset *= this.shape[i+1];
                index += pos[i] * offset;
            }
            index += pos[pos.Length - 1];
            this.data[index] = data;
        }

        ~Tensor()
        {
            this.shape = null;
            this.data = null;
        }

        public T[] GetData()
        {
            return this.data;
        }

        public TensorType GetDType()
        {
            return this.dtype;
        }

        public int[] GetShape()
        {
            return this.shape;
        }

        public int GetDimensionShape(int dimension)
        {
            return this.shape[dimension];
        }

        public T GetData(int[] pos)
        {
            if (pos.Length > this.shape.Length) throw new ArgumentException("target pos is not in valid");
            int index = 0;
            index += pos[0] * this.shape[1];
            index += pos[1];
            return this.data[index];
        }

        public bool CompareShape(int[] target)
        {
            if (this.shape == null||target==null) return false; 
            if (target.Length != this.shape.Length) return false;
            for(int i = 0; i < this.shape.Length; i++)
            {
                if (this.shape[i] != target[i]) return false;
            }
            return true;
        }

        public int GetLength()
        {
            if (this.shape == null) return 0;
            int sum = 1;
            for (int i = 0; i < shape.Length; i++)
            {
                sum *= (int)shape[i];
            }
            return sum;
        }

       
           
    }

    public enum TensorType
    {
        TENSOR_INT,
        TENSOR_FLOAT
    }



}
